﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SyncList.Business.ValueObject;

namespace SyncList.Business.Services
{


    /// <summary>
    /// Traitement
    /// </summary>
    class FusionService : IFusionService
    {

       

        /// <summary>
        /// Organiser plusieurs fichiers sous forme d'une unique arborescence explorable.
        /// Les fichiers de l'utilisateur en cours ne sont pas visibles mais servent à définir les flags.
        /// </summary>
        /// <param name="dataList">Liste de fichiers</param>
        /// <param name="currentUserName">Utilisateur courant</param>
        /// <returns>Arborescence</returns>
        public DirectoryContent OrganizeInDirectories(IEnumerable<Data> dataList, string currentUserName)
        {
            Dictionary<string, List<string>> userHashs = new Dictionary<string,List<string>>();

            DirectoryContent root = new DirectoryContent(null, "");
            root.DirectoryType = DirectoryTypeEnum.Root;
            List<FileItem> myFiles = new List<FileItem>();    
            
            foreach (Data data in dataList)
            {
              
                string rootName = data.UserName;
                if (String.IsNullOrWhiteSpace(rootName)) 
                    rootName = "?";

                DirectoryContent userDirectory = root.GetDirectory(rootName);
                userDirectory.DirectoryType = DirectoryTypeEnum.User;

                foreach (FileItem file in data.Files)
                {
                    string fullPath = file.LocalFolder;
                    if (!fullPath.EndsWith(@"\"))
                        fullPath += @"\";

                    file.UserName = data.UserName;

                    if (!userHashs.ContainsKey(data.UserName))
                    {
                        userHashs.Add(data.UserName, new List<string>());
                    }

                    // - Si le Hash n'est pas encore connu pour cet utilisateur, je l'ajoute 
                    if (!userHashs[data.UserName].Contains(file.Hash))
                    {
                        userHashs[data.UserName].Add(file.Hash);
                        userDirectory.PlaceFileInTree(file, fullPath);
                    }
                 
                }
            }
            return (root);
        }



        /// <summary>
        /// Cocher les fichiers que j'ai déjà
        /// </summary>
        /// <param name="root">Racine de l'arbre</param>
        /// <param name="listOfFileToCompare">Liste des fichiers à comparer</param>
        /// <param name="currentUserName">Utilisateur en cours</param>
        public void CheckFiles(DirectoryContent root, List<Data> listOfFileToCompare, string currentUserName)
        {
            
            IEnumerable<Data> myFiles = listOfFileToCompare.Where(f => currentUserName.Equals(f.UserName));
            IEnumerable<Data> strangerFiles = listOfFileToCompare.Where(f => !currentUserName.Equals(f.UserName));

            // - Faire une liste de tous mes Hash
            List<string> myFilesHash = new List<string>();
            foreach (Data data in myFiles)
            {
                foreach (FileItem def in data.Files)
                {
                    myFilesHash.Add(def.Hash);

                    def.State = ExplorerItemState.IHaveFile;
                }
            }
            

            // - Définir la couleur des fichiers (et dossiers)
            foreach (Data data in strangerFiles)
            {
                foreach (FileItem def in data.Files)
                {
                    

                    if (myFilesHash.Contains(def.Hash))
                        def.State = ExplorerItemState.IHaveFile;
                    else
                        def.State = ExplorerItemState.IDontHaveFile;

                }                 
            }

            // - Définir la couleur des dossiers, trier par dossier à partir du plus profond. Si un dossier ne contient que des fichiers copiés, il apparait aussi en vert
            CheckDirectoriesStates(root);
            //foreach (DirectoryContent directory in root.AllDirectories.OrderByDescending(l => l.Level))
            //{
            //    List<IGrouping<ExplorerItemState, ItemBase>> results = directory.Items.GroupBy(i => i.State).ToList();
            //    if (results.Count == 1) // - Si j'ai le même état partout, je propage ! : je copie l'état unique au dossier parent
            //        directory.State = results[0].Key;
            //}

        }

        /// <summary>
        /// Vérifier que tous les fichiers d'un dossier sont d'un même état pour propager cet état
        /// </summary>
        public void CheckDirectoriesStates(DirectoryContent root)
        {
            // - Définir la couleur des dossiers, trier par dossier à partir du plus profond. Si un dossier ne contient que des fichiers copiés, il apparait aussi en vert
            foreach (DirectoryContent directory in root.AllDirectories.OrderByDescending(l => l.Level))
            {
                List<IGrouping<ExplorerItemState, ItemBase>> results = directory.Items.GroupBy(i => i.State).ToList();
                if (results.Count == 1) // - Si j'ai le même état partout, je propage ! : je copie l'état unique au dossier parent
                    directory.State = results[0].Key;
            }
        }

    }
}
